package cn.nvr.file.conversion.controller;

import cn.nvr.file.conversion.config.FileConfig;
import cn.nvr.file.conversion.enu.FileTypeEnu;
import cn.nvr.file.conversion.util.JacobOffice2PdfUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ZeroCopyHttpOutputMessage;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

@AllArgsConstructor
@RestController
@Api("文件转换")
public class FileController {

    private final FileConfig fileConfig;

    private final JacobOffice2PdfUtil word2Pdf;

    @ApiOperation("文件上传")
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Mono<String> requestBodyFlux(@RequestPart("file") FilePart filePart) throws IOException {

        String fileUUID = UUID.randomUUID().toString();
        Path sourceFilePath = Paths.get(fileConfig.getSourceFilePath(), fileUUID + ".doc");
        return filePart.transferTo(sourceFilePath)
                .doOnSuccess(x ->
                        word2Pdf.convert2PDF(sourceFilePath.toString(),
                                FileTypeEnu.WORD,
                                Paths.get(fileConfig.getTargetFilePath(), fileUUID + ".pdf").toString()
                        )
                )
                .map(x -> fileUUID);
    }

    @GetMapping("/checkFile/{fileName}")
    public Mono<Boolean> hasFile(@PathVariable String fileName) {
        return Mono.just(Files.exists(Paths.get(fileConfig.getTargetFilePath(), fileName)));
    }

    @GetMapping("/download/{fileName}")
    public Mono<Void> downloadByWriteWith(@PathVariable String fileName, ServerHttpResponse response) throws IOException {
        ZeroCopyHttpOutputMessage zeroCopyResponse = (ZeroCopyHttpOutputMessage) response;

        HttpHeaders headers = zeroCopyResponse.getHeaders();
        headers.set("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
        headers.set("file-name", URLEncoder.encode(fileName, "UTF-8"));
        headers.set("Access-Control-Allow-Origin", "*");
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        File file = Paths.get(fileConfig.getSourceFilePath(), fileName).toFile();
        return zeroCopyResponse.writeWith(file, 0, file.length());
    }

    @PostConstruct
    private void init() throws IOException {
        Files.createDirectories(Paths.get(fileConfig.getSourceFilePath()));
        Files.createDirectories(Paths.get(fileConfig.getTargetFilePath()));
    }
}
